using System.ComponentModel;
using Microsoft.Practices.Unity;

namespace $safeprojectname$.ViewModels
{
    /// <summary>
    /// Represents the base class used by all view models.
    /// </summary>
    /// <remarks>
    /// All view models should be derived from this class in order to maintain common behavior.
    /// </remarks>
    public abstract class ViewModelBase : IViewModel, INotifyPropertyChanged
    {
        private string title;
        private ViewModelMode mode;

        /// <summary>
        /// Initializes a new instance of the <see cref="ViewModelBase"/> class.
        /// </summary>
        /// <param name="unityContainer">The unity container.</param>
        protected ViewModelBase(IUnityContainer unityContainer)
        {
            UnityContainer = unityContainer;
            Mode = ViewModelMode.Default;
        }

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Gets or sets the title of the view.
        /// </summary>
        /// <value>The title.</value>
        public virtual string Title
        {
            get { return title; }
            set
            {
                title = value;
                OnPropertyChanged("Title");
            }
        }

        /// <summary>
        /// Gets or sets the mode of the view model.
        /// </summary>
        /// <value>The mode.</value>
        public ViewModelMode Mode
        {
            get { return mode; }
            set
            {
                mode = value;
                OnPropertyChanged("Mode");
                OnSetViewState();
            }
        }

        /// <summary>
        /// Fires the <see cref="PropertyChanged"/> event passing the given property name.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Gets the unity container instance.
        /// </summary>
        /// <value>The unity container.</value>
        protected IUnityContainer UnityContainer { get; private set; }

        /// <summary>
        /// Called when the an operation on the model or an exception changes the state of the view model. This methos can be used to perform common operations such as 
        /// enabling/disabling button on the view end or changes the value of other bounded properties.
        /// </summary>
        protected virtual void OnSetViewState()
        {
        }
    }
}